package components;

import images.Images;

import com.uqbar.vainilla.DeltaState;
import com.uqbar.vainilla.appearances.Sprite;
import components.direction.Direction;
import components.scenes.MainGameScene;
import components.scenes.Slot;

public abstract class Walker extends PacmanComponent {

	private double speed;
	private Direction dir;
	private boolean canMove;
	private int currentX;
	private int currentY;
	private Direction queuedDir;
	private WalkerState walkerState;
	
	public Walker(int aDiameter, int aHeight, double x, double y) {
		super(aDiameter, aHeight, x, y);
		this.canMove = true;
		this.dir = new Direction(1, 0);
		this.currentX = 0;
		this.currentY = 0;
		this.setSpeed(50);
		this.setQueuedDir(this.dir);
		this.walkerState = new ChangingDirection(this);
	}

	public Direction getDir() {
		return dir;
	}

	public void setDir(Direction dir) {
		this.dir = dir;
		this.updateAppearance(dir);
	}
	
	private void updateAppearance(Direction dir) {
		this.setAppearance(this.getSprite(dir));
	}

	public double getSpeed() {
		return speed;
	}

	public void setSpeed(double speed) {
		this.speed = speed;
	}

	public WalkerState getWalkerState() {
		return walkerState;
	}

	public void setWalkerState(WalkerState walkerState) {
		this.walkerState = walkerState;
	}

	public Direction getQueuedDir() {
		return queuedDir;
	}

	public void setQueuedDir(Direction queuedDir) {
		this.queuedDir = queuedDir;
	}


	public Slot calculateNextSlot(Direction dir) {
		return this.getScene().nextSlot(this.getCurrentX(), this.getCurrentY(), dir);
	}

	public void effectiveUpdate(DeltaState delta){

		this.getWalkerState().update(delta);
	}

	public Slot nextSlot() {
		return this.calculateNextSlot(this.getQueuedDir());
	}

	public boolean canMove() {
		return canMove;
	}

	public void setCanMove(boolean canMove) {
		this.canMove = canMove;
	}

	public int getCurrentX() {
		return currentX;
	}

	public void setCurrentX(int currentX) {
		this.currentX = currentX;
	}

	public int getCurrentY() {
		return currentY;
	}

	public void setCurrentY(int currentY) {
		this.currentY = currentY;
	}

	public Slot getMovingTo() {
		return this.getScene().nextSlot(this.getCurrentX(), this.getCurrentY(), this.getDir());
	}

	public void updateSlot() {
		if(this.canMove()){
			this.setCurrentX(this.getCurrentX() + this.getDir().getVx());
			this.setCurrentY(this.getCurrentY() + this.getDir().getVy());
		}
		
	}

	public void updateDirection() {
		if (!this.nextSlot().isSolid()){
			this.setDir(this.getQueuedDir());
		}
	}

	@Override
	public Shape defineShape() {
		return new CircularShape(this);
	}

	@Override
	public void addToScene(MainGameScene mainGameScene, int x, int y) {
		mainGameScene.addComp(this, x, y);
	}

	public Sprite getSprite(Direction dir){
		int dirsum = dir.getVx() + dir.getVy()*2;
		Sprite sp = Images.getImage(this.appRootName());
		
		if(dirsum == 2){
			return sp.rotate(Math.toRadians(90));
		}else if(dirsum == 1){
			return sp;
		}else if(dirsum == -1){
			return sp.rotate(Math.toRadians(180));
		}else {
			return sp.rotate(Math.toRadians(270));
		}
	}
	public abstract String appRootName();
}
